home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i126: tar - tape archive utility, Part01/05
- Message-ID: <11979@xanth.cs.odu.edu>
- Date: 29 Mar 90 03:08:05 GMT
- Sender: tadguy@cs.odu.edu
- Reply-To: hue@netcom.uucp (Jonathan Hue)
- Lines: 2011
- Approved: tadguy@cs.odu.edu (Tad Guy)
- X-Mail-Submissions-To: Amiga@cs.odu.edu
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: hue@netcom.uucp (Jonathan Hue)
- Posting-number: Volume 90, Issue 126
- Archive-name: unix/tar/part01
-
- I finally found the time to finish and test this program. This is tar
- for the Amiga, fully compatible with UNIX tar, plus some Amiga enhancements,
- such as preservation of all mode bits, comments, and timestamp down to
- ticks. This is based on John Gilmore's public domain tar.
-
- Mail bug reports to me and I'll fix them.
-
- -Jonathan
- apple!netcom!hue
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 5)."
- # Contents: Makefile PORTING README README.1st README.AMIGA TODO
- # amiga.c diffarch.c dir.c dirent.h getoldopt.c getopt.c open3.h
- # port.h stat.h tar.h tar.lnk types.h utime.c wildmat.c
- # Wrapped by tadguy@xanth on Wed Mar 28 22:07:07 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(345 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XCC = lc
- XCFLAGS = -O -DNONAMES -DDEFBLOCKING=20
- X
- XSRCS = buffer.c create.c diffarch.c extract.c getoldopt.c getopt.c list.c \
- X port.c tar.c utime.c wildmat.c amiga.c
- X
- XOBJS = buffer.o create.o diffarch.o extract.o getoldopt.o getopt.o list.o \
- X port.o tar.o utime.o wildmat.o amiga.o
- X
- Xall: tar
- X
- Xtar: $(OBJS)
- X blink with tar.lnk
- X
- Xclean:
- X rm *.o tar
- END_OF_FILE
- if test 345 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'PORTING' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'PORTING'\"
- else
- echo shar: Extracting \"'PORTING'\" \(2963 characters\)
- sed "s/^X//" >'PORTING' <<'END_OF_FILE'
- X Porting hints for public domain tar
- X John Gilmore, ihnp4!hoptoad!gnu
- X @(#)PORTING 1.13 87/11/11
- X
- XThe Makefile should be edited to comment out all the undesired
- Xversions, and create the following configuration lines for the system
- Xyou are compiling it on:
- X
- XDEFS = the proper #define's to conditionally compile for your system.
- XLIBS = the system libraries and/or object modules to link with the program.
- XLINT = the lint program (or the compiler with extra checking turned on)
- XLINTFLAGS = a good strong way to invoke 'lint' on your system.
- XDEF_AR_FILE = the name of the default archive file on your system.
- X It should be enclosed in quoted quotes, e.g. \"/dev/foo\" .
- XDEFBLOCKING = the default blocking factor on your system.
- XO = the suffix for object files ('o', except 'obj' for MSDOS).
- X
- XA copy of "getopt", the standard argument parser, is required. It's in
- Xlibc on Missed'em V systems and 4.3BSD; on most other systems, you'll
- Xneed a copy of a public domain getopt, available through the
- Xcomp.sources.unix archives, or from the AT&T Toolchest if you can't
- Xfind it elsewhere.
- X
- XA copy of the Berkeley directory access routines is also required.
- XThese are in libc and <sys/dir.h> on Berkeley systems. A public domain
- Xversion is available through comp.sources.unix. There is an #include
- Xyou have to change in create.c for this, to set the name of the include
- Xfile you have. Some systems have the include file in <sys/ndir.h>.
- XYou'll have to find it on your system, or get the public domain one and
- Xplace it somewhere. For MSDOS, I have supplied these directory
- Xroutines in msd_dir.c and msd_dir.h, since it's likely that your system
- Xdoesn't have them. To permanently install these into your MSC 3.0
- Xlibrary, do the following:
- X copy msd_dir.h c:\c\include\sys\dir.h
- X cl -A$(MODEL) -c msd_dir.c
- X lib $(MODEL)dir.lib msd_dir.obj;
- XChange c:\c\include to wherever your standard include directory is.
- XYou might have to modify this procedure if you aren't using MSC 3.0.
- X
- XGrep for FIXME to find places that aren't finished or which have
- Xportability problems. Also see the file TODO.
- X
- XThe MSDOS port was done under the Microsoft C 3.0 compiler and
- Xlibraries. In the Makefile, COPTS should be changed to -Zi or nothing;
- Xand there is a special link command for making tar.exe, which you will
- Xhave to uncomment, since MSDOS can't handle command lines longer than
- X128 bytes. Also, clean and install will not work unless you change
- X/ in path names to \.
- X
- XOn Minix, there are a bunch of problems. "V7 compatible" my ass.
- X * "make" doesn't expand macros in the Makefile properly. You will
- Xprobably have to expand them by hand. Better to go in and fix Minix
- X"make" though...
- X * The directory access library is nonexistent. It wasn't in V7 but
- Xanybody who writes code without it, even on V7 systems, is a fool.
- X * Various other library routines are broken, e.g. printf() doesn't take
- X"%*s" or "%.*s"; no <sys/types.h> which Unix requires, ctime(), getopt().
- END_OF_FILE
- if test 2963 -ne `wc -c <'PORTING'`; then
- echo shar: \"'PORTING'\" unpacked with wrong size!
- fi
- # end of 'PORTING'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2695 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThis is the Nov87 release of a public domain tar(1) replacement. It
- Ximplements the 'c', 'x', and 't' commands of Unix tar, and many of the
- Xoptions. It creates P1003 "Unix Standard" [draft 6] tapes by default,
- Xand can read and write both old and new formats. It can compress or
- Xdecompress tar archives "on the fly" (using the 'z' option) as well as
- Xaccessing remote tape drives or files by specifying
- X"host:/dev/tapedrive". It lets you set the default tape drive by
- Xsetting TAPE in your environment. Its verbose output looks more like
- X"ls -l" than the Unix tar, the columns line up, and you can get verbose
- Xlistings from the 'cvv' option as well as from 'xvv' and 'tv'. It does
- Xshell-globbing (regular expressions) for listing and extraction. It is
- Xa little better at reading damaged tapes than Unix tar. There is a
- Xhalf-baked "diff" option for comparing a tape against the file system.
- XAnd it's free.
- X
- XIt is designed to be a lot more efficient than the standard Unix tar;
- Xit does as little bcopy-ing as possible, and does file I/O in large
- Xblocks. On the other hand, it has not been timed or performance-tuned;
- Xit's just *designed* to be faster.
- X
- XOn SunOS 3.3, the tar archives it creates under the 'old' option are
- Xbyte-for-byte the same as those created by /bin/tar, except the trash
- Xat the end of each file and at the end of the archive has been replaced
- Xby zeroes.
- X
- XIt was written and initially debugged on a Sun Workstation running
- X4.2BSD. It has been run on Xenix, Unisoft, Vax 4.2BSD, utzoonix, USG,
- XMasscomp, Minix, and MSDOS systems. I'm interested in finding people
- Xwho will port it to other types of (Unix and non-Unix) systems, use it,
- Xand send back the changes; and people who will add the obscure tar
- Xoptions that they happen to use and I don't. In particular, VMS, Mac,
- XAtari and Amiga versions would be handy.
- X
- XIt still has a number of loose ends, marked by "FIXME" comments in the
- Xsource. Fixes to these things are also welcome.
- X
- XI am the author of all the code in this program, except some of the
- Xsubroutines, which are from contributors listed below. I hereby place
- Xit in the public domain. If you modify it, or port it to another
- Xsystem, please send me back a copy, so I can keep a master source.
- X
- XThis program is much better than it started, due to the effort and care
- Xput in by Henry Spencer, Fred Fish, Ian Darwin, Geoff Collyer, Stan
- XBarber, Guy Harris, Dave Brower, Richard Todd, Michael Rendell, Stu
- XHeiss, and Rich $alz. Thank you, one and all.
- X
- X John Gilmore
- X Nebula Consultants
- X PO Box 170608
- X San Francisco, California, USA 94117-0608
- X hoptoad!gnu or gnu@toad.com
- X Hoptoad talks to sun, ptsfa, ihnp4, utzoo, ucsfcgl.
- X
- X@(#)README 1.14 87/11/11
- END_OF_FILE
- if test 2695 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'README.1st' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.1st'\"
- else
- echo shar: Extracting \"'README.1st'\" \(322 characters\)
- sed "s/^X//" >'README.1st' <<'END_OF_FILE'
- X
- XIf you want to make tar, you'll have to move some files around because
- XI grabbed some .h and dirlib.c from other directories and put them here.
- X
- XYou'll get some warning when compiling because I never got around to
- Xgoing back and casting the return values from some functions which
- Xwere declared to return BPTR.
- X
- X-Jonathan
- END_OF_FILE
- if test 322 -ne `wc -c <'README.1st'`; then
- echo shar: \"'README.1st'\" unpacked with wrong size!
- fi
- # end of 'README.1st'
- fi
- if test -f 'README.AMIGA' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.AMIGA'\"
- else
- echo shar: Extracting \"'README.AMIGA'\" \(3736 characters\)
- sed "s/^X//" >'README.AMIGA' <<'END_OF_FILE'
- XAmiga Tar
- X
- XThis is tar for the Amiga. I used John Gilmore's (gnu@toad.COM) public
- Xdomain tar program as a base for this tar. This program, and the files it
- Xproduces are supposed to be fully compatible with UNIX tar.
- X
- XAmiga Specific Features
- X
- XThere are a couple of Amiga specific features which I've added. In an unused
- Xpart of the header I store a magic number, the original Amiga file bits, the
- Xfile's date stamp (including ticks), and the file comment. When this program
- Xextracts it looks for the magic number. If it is present, it uses the stored
- Xfile bits to set the mode rather than the mode stored in the regular tar
- Xheader. The file's comment is also set, and the timestamp set from the
- Xoriginal timestamp. There is also some filename translation which goes on,
- Xeach leading / translates to ../, null string translates to ./, so the files
- Xare compatible with UNIX. The reverse of these translations is done when
- Xextracting. Since some shells have difficulty giving tar a null string as an
- Xargument, "." can be used to specify the current directory, as in
- X"tar cvf ram:mybackup ." to add every file in and below the current directory
- Xto the tar archive. You may need to quote the single period in some shells,
- Xlike Sksh, as it will expand to the absolute pathname otherwise.
- X
- XArchiving
- X
- XIf you specify the modifier "a" on the command line, the archived bit of every
- Xfile will be set as it is added to the tar archive. You can use tar as a file
- Xbackup utility this way. Regardless of command line options, the archived bit
- Xis always cleared upon extraction.
- X
- XIf you specify the modifier "A" on the command line, tar will not archive
- Xany regular file which has its archived bit set. Directories are always
- Xwritten to the archive.
- X
- XDifferences
- X
- XIf you say something like "tar cvf ram:foo .", the output might not be what
- Xyou would expect. To get the normal amount of verbosity, you need to specify
- X"v" twice, as in "tar cvvf ram:foo". I think the reason this was done is so
- Xthat a single v will give you a list of filenames you can easily edit,
- Xsomething a normal tar won't do. You should also realize that you can't
- Xset protection, comment, or datestamp on a root directory. Tar can fail when
- Xsetting protection, comment, and datestamp on a directory. This will happen
- Xif someone is holding a lock on the directory. Tar tries to be clever
- Xand cd up one level when setting stuff on the current directory, but this
- Xwill fail if anyone else has a lock on the directory. Tar complains loudly
- Xwhen this happens. Tar works with CrossDOS, but setting the comment fails
- Xof course.
- X
- XEnvironment variables
- X
- XYou will want to set a couple environment variables for tar. You should set
- XTZ, just like in UNIX. For me the command line is "setenv TZ PST8PDT".
- XIf you don't set TZ, tar uses "CST6CDT" as the default. The second
- Xenvironment variable is "TARFILE", which is the name of the default
- Xfile to create. You should do something like "setenv TARFILE ram:tarfile".
- XIf you don't set TARFILE, it defaults to "ram:tarfile".
- X
- XWhy tar?
- X
- XThere are a lot of reasons for using tar. It preserves the directory
- Xstructure, it's fast, it restores all the information that goes along
- Xwith a file, and it's used on UNIX boxes.
- X
- XBugs
- X
- XWhile I've tried to test this as much I can, I can't guarantee that there
- Xaren't any bugs. So use this at your own risk.
- X
- XFor reasons I don't understand, tar cannot set the timestamp on files in
- Xthe current directory when the files reside on the ASDG recoverable RAM
- XDISK. It works fine with everything else I've tried. If you look at the
- Xcode in utime.c, the ParentDir() call returns zero. The files are still
- Xextracted ok, but the timestamps are not changed.
- X
- XJonathan Hue
- Xhue@netcom.UUCP
- END_OF_FILE
- if test 3736 -ne `wc -c <'README.AMIGA'`; then
- echo shar: \"'README.AMIGA'\" unpacked with wrong size!
- fi
- # end of 'README.AMIGA'
- fi
- if test -f 'TODO' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'TODO'\"
- else
- echo shar: Extracting \"'TODO'\" \(2713 characters\)
- sed "s/^X//" >'TODO' <<'END_OF_FILE'
- X@(#) TODO 1.15 87/11/06
- X
- XTest owner/group on extraction better.
- X
- Xcreation of links, symlinks, nodes doesn't follow the -k (f_keep) guidelines;
- Xif the file already exists, it is not replaced, even though no -k.
- X
- XCheck stderr and stdout for errors after writing, and quit if so.
- X
- XPreliminary design of Multifile option to handle EOFs on input and
- Xoutput. Multifile can just close the archive when it hits end of
- Xarchive, and ask for archive to be changed. It has no choice on some
- Xmedia, e.g. floppies and cartridge tapes, where there is no room for an
- XEOF block there. Start off 2nd archive medium with odd header block,
- Xduplicating original, but with offset to start of data spec'd. Reading
- Xsuch a header causes tar non-'M' to complain while extracting (but to
- Xseek there and do it anyway!) Big win -- this works on cartridge
- Xtapes, should work on floppies, might work on magtape. It would
- Xencourage the *&%#$ systems programmers to fix their drivers, too!
- X
- XProfile it and see where the time, call counts, etc are going.
- X
- XFix directory timestamps after inserting files into them. Wait til next
- Xfile that's not in the directory. Need a stack of them.
- X
- XOption to seek the input file (in skip_file) rather than reading
- Xand tossing it? (Could just jump in buffer if stuff is in core.)
- XCould misalign archive reads versus filesys and slow it down, who knows?
- X
- XAdd -C option for creating from odd directories a la 4.2BSD?
- X
- XBreak out odd bits of code into separate support modules.
- X
- XAdd the r, u, X, l, F, C, and digit options of Unix tar.
- X
- XV8 tar does something that is quite handy when reading tapes written on
- X4.2 system into non-4.2 systems: it reduces file name components to
- X14 bytes or less and ensures that they are unique (I think it truncates
- Xto 10 bytes and appends "..aa" where aa are two unique letters) and puts
- Xout a file containing the mapping between long names on tape and short
- Xnames on disk.
- X
- XClean up 'd' (diff) option. Currently it works for regular files
- Xand symlinks, needs work for dirs and links. Ideally, output should
- Xlook like "diff -r" or -rl after an extract of the tape and a real diff.
- XRight now it's very messy. To do the above, we'd need to read the
- Xdirectories that we touch and check all the file names against what's
- Xon the tape. All we do now is check the file contents and stats.
- X
- XCheck "int" variables to see if they really need to be long (file sizes,
- Xrecord counts, etc). Sizes of in-core buffers should be int; since
- Xmalloc() takes an int argument we can never allocate one any bigger.
- XMaybe unsigned int would be better, though. Little system people,
- Xhelp me out here! (E.g. run lint on it on your system and send me
- Xthe result if it shows anything fixable.)
- END_OF_FILE
- if test 2713 -ne `wc -c <'TODO'`; then
- echo shar: \"'TODO'\" unpacked with wrong size!
- fi
- # end of 'TODO'
- fi
- if test -f 'amiga.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'amiga.c'\"
- else
- echo shar: Extracting \"'amiga.c'\" \(6424 characters\)
- sed "s/^X//" >'amiga.c' <<'END_OF_FILE'
- X#include <exec/types.h>
- X#include <libraries/dos.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <errno.h>
- X#define NARGS /* get it to shut up about my mkdir */
- X#include <stdio.h>
- X#include "tar.h"
- X
- Xumask(int mask)
- X{
- X return (0);
- X}
- X
- Xstat(char *filename, struct stat * statbuf)
- X{
- X struct FileLock *alock, *parent;
- X struct FileInfoBlock *fib;
- X int modes;
- X extern long timezone;
- X
- X if ((!statbuf) || (!filename))
- X {
- X errno = EFAULT;
- X return (-1);
- X }
- X if (alock = Lock(filename, ACCESS_READ))
- X {
- X if ((fib = (struct FileInfoBlock *) malloc(sizeof(*fib))) == NULL)
- X {
- X UnLock(alock);
- X errno = ENOMEM;
- X return (-1); /* malloc failed */
- X }
- X Examine(alock, fib);
- X if (!(parent = ParentDir(alock)))
- X {
- X statbuf->st_mode = 0700;
- X statbuf->st_prot = ~0xf;
- X }
- X else
- X {
- X UnLock(parent);
- X modes = (~fib->fib_Protection >> 1) & 0x7;
- X statbuf->st_mode = (modes << 6);
- X statbuf->st_prot = fib->fib_Protection;
- X }
- X if (fib->fib_EntryType > 0)
- X statbuf->st_mode |= S_IFDIR;
- X else
- X statbuf->st_mode |= S_IFREG;
- X statbuf->st_dev = 0;
- X statbuf->st_ino = 0;
- X statbuf->st_size = fib->fib_Size;
- X statbuf->st_rdev = fib->fib_DiskKey;
- X statbuf->st_gid = 0;
- X statbuf->st_uid = 0;
- X
- X /*
- X * getft() doesn't compensate for time zones.
- X */
- X statbuf->st_mtime = getft(filename) + timezone;
- X statbuf->st_nlink = 1;
- X
- X /*
- X * These next fields really only exist for Amiga tar's benefit
- X */
- X strcpy(statbuf->st_comment, fib->fib_Comment);
- X memcpy((char *) &(statbuf->st_date), (char *) &(fib->fib_Date),
- X sizeof(statbuf->st_date));
- X free(fib);
- X UnLock(alock);
- X return (0);
- X } else
- X {
- X errno = ENOENT;
- X return (-1); /* couldn't access file */
- X }
- X}
- X
- X
- X/*
- X * Convert Amiga style path to UNIX style. Does the following conversions:
- X * ull string => ./ leading / => ../
- X */
- Xchar *
- XcvtAmi2UNIX(char *src, char *dst)
- X{
- X char *dstp,
- X *srcp;
- X
- X if (!*src)
- X {
- X strcpy(dst, "./");
- X return (dst);
- X }
- X dstp = dst;
- X srcp = src;
- X/*
- X * Each leading / converts to ../
- X */
- X while (*srcp == '/')
- X {
- X *dstp++ = '.';
- X *dstp++ = '.';
- X *dstp++ = '/';
- X srcp++;
- X }
- X while (*dstp++ = *srcp++) /* copy rest of chars */
- X ;
- X return (dst);
- X}
- X
- X/*
- X * Convert UNIX style path to Amiga style. Does the following conversions:
- X * / => null string ../ => /
- X */
- XcvtUNIX2Ami(char *dst)
- X{
- X char *dstp,
- X *srcp,
- X src[NAMSIZ + 2];
- X
- X strcpy(src, dst);
- X dstp = dst;
- X srcp = src;
- X
- X while (*srcp == '.')
- X {
- X if (*(srcp + 1) == '/')
- X srcp += 2; /* ./ gets skipped */
- X else if ((*(srcp + 1) == '.') && (*(srcp + 2) == '/'))
- X {
- X srcp += 3; /* ../ turns into / */
- X *dstp++ = '/';
- X } else
- X break;
- X }
- X while (*dstp++ = *srcp++) /* copy rest of chars */
- X ;
- X return (dst);
- X}
- X
- X
- X/*
- X * Wrapper for SetComment. "Smart" because it knows how to handle "", and
- X * handle case if current directory is root. But not so smart it can handle
- X * case when we're sitting in a directory it wants to SetComment on other than
- X * "".
- X */
- XSmartSetComment(char *filename, char *comment)
- X{
- X extern int SetComment();
- X
- X if (!*comment)
- X return(0);
- X else
- X return(SmartDoSomething(filename, (int) comment, SetComment,
- X "SetComment"));
- X}
- X
- X
- X/*
- X * Wrapper for SetProtection. "Smart" because it knows how to handle "", and
- X * handle case if current directory is root. But not so smart it can handle
- X * case when we're sitting in a directory it wants to SetProtection on other
- X * than "".
- X */
- XSmartSetProtection(char *filename, int protection)
- X{
- X extern int SetProtection();
- X
- X return(SmartDoSomething(filename, protection, SetProtection,
- X "SetProtection"));
- X}
- X
- X
- XSmartDoSomething(char *filename, int arg, int (*doSomething)(), char *funcstr)
- X{
- X struct FileLock *lock = 0, *parentLock;
- X struct FileInfoBlock *fib = 0;
- X int retval;
- X
- X if (*filename)
- X {
- X if (!(*doSomething)(filename, arg))
- X {
- X errno = ENOENT;
- X return(-1);
- X }
- X else
- X return(0);
- X }
- X if (filename[strlen(filename) - 1] == ':')
- X {
- X errno = EACCES; /* root dir */
- X return(-1);
- X }
- X
- X /*
- X * "" (current directory) case
- X *
- X * There are a couple things to worry about here. First of all, you have
- X * to find the parent directory, and the name of the current directory.
- X * But if there is no parent, you can't set the comment. Once you get
- X * past this, you have to change directories and unlock the old current
- X * directory because you can't set the protection on a busy directory.
- X */
- X if (!(lock = Lock("", ACCESS_READ)))
- X {
- X errno = ENOENT;
- X return (-1);
- X }
- X if (!(parentLock = ParentDir(lock)))
- X {
- X UnLock(lock);
- X errno = EACCES; /* root dir */
- X return (-1);
- X }
- X if (!(fib = (struct FileInfoBlock *) malloc(sizeof(*fib))))
- X {
- X UnLock(lock);
- X errno = ENOMEM;
- X return (-1);
- X }
- X Examine(lock, fib);
- X UnLock(lock); /* free Lock obtained by Lock("",) */
- X
- X /*
- X * At this point we have a FileInfoBlock with the name of this directory,
- X * and a lock on our parent directory. CD to the parent directory, unlock
- X * the old directory, and set the comment.
- X */
- X lock = CurrentDir(parentLock);
- X UnLock(lock); /* free Lock held by shell??? */
- X if (!(*doSomething)(fib->fib_FileName, arg))
- X {
- X errno = ENOENT;
- X retval = -1;
- X }
- X else
- X retval = 0;
- X
- X /*
- X * Whew, now cleanup. Remember, we are now in the parent directory.
- X */
- X lock = Lock(fib->fib_FileName);
- X parentLock = CurrentDir(lock);
- X UnLock(parentLock);
- X free(fib);
- X return (retval);
- X}
- X
- X/*
- X * Lattice C perror() puts out a leading \n - this is the wrong behavior
- X */
- Xperror(char *s)
- X{
- X if ((errno >= 0) && (errno <= sys_nerr))
- X {
- X fputs(s, stderr);
- X fputs(": ", stderr);
- X fputs(sys_errlist[errno], stderr);
- X putc('\n', stderr);
- X fflush(stderr); /* why do I have to do this??? It shouldn't
- X be buffered. */
- X }
- X return(errno);
- X}
- X
- X/*
- X * It's probably cleaner to write my own mkdir() which takes two arguments,
- X * rather than paste in the code to set the mode everywhere mkdir() is
- X * called
- X */
- Xmkdir(char *dirname, int mode)
- X{
- X struct FileLock *lock;
- X
- X if (lock = CreateDir(dirname))
- X {
- X UnLock(lock);
- X return(SmartSetProtection(dirname, (~(((mode & 0700) >> 5) | 1)) & 0xf));
- X }
- X else
- X {
- X if (IoErr() == ERROR_DIRECTORY_NOT_EMPTY)
- X return(0);
- X errno = EACCES; /* FIXME */
- X return(-1);
- X }
- X}
- END_OF_FILE
- if test 6424 -ne `wc -c <'amiga.c'`; then
- echo shar: \"'amiga.c'\" unpacked with wrong size!
- fi
- # end of 'amiga.c'
- fi
- if test -f 'diffarch.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'diffarch.c'\"
- else
- echo shar: Extracting \"'diffarch.c'\" \(7394 characters\)
- sed "s/^X//" >'diffarch.c' <<'END_OF_FILE'
- X/*
- X * Diff files from a tar archive.
- X *
- X * Written 30 April 1987 by John Gilmore, ihnp4!hoptoad!gnu.
- X *
- X * @(#) diffarch.c 1.10 87/11/11 Public Domain - gnu
- X */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#ifdef BSD42
- X#include <sys/file.h>
- X#endif
- X
- X#ifdef USG
- X#include <fcntl.h>
- X#endif
- X
- X/* Some systems don't have these #define's -- we fake it here. */
- X#ifndef O_RDONLY
- X#define O_RDONLY 0
- X#endif
- X#ifndef O_NDELAY
- X#define O_NDELAY 0
- X#endif
- X
- Xextern int errno; /* From libc.a */
- Xextern char *valloc(); /* From libc.a */
- X
- X#include "tar.h"
- X#include "port.h"
- X
- Xextern union record *head; /* Points to current tape header */
- Xextern struct stat hstat; /* Stat struct corresponding */
- Xextern int head_standard; /* Tape header is in ANSI format */
- X
- Xextern void print_header();
- Xextern void skip_file();
- X
- Xchar *filedata; /* Pointer to area for reading
- X file contents into */
- X
- X/*
- X * Initialize for a diff operation
- X */
- Xdiff_init()
- X{
- X
- X /*NOSTRICT*/
- X filedata = (char *) valloc((unsigned)blocksize);
- X if (!filedata) {
- X fprintf(stderr,
- X "tar: could not allocate memory for diff buffer of %d bytes\n",
- X blocking);
- X exit(EX_ARGSBAD);
- X }
- X}
- X
- X/*
- X * Diff a file against the archive.
- X */
- Xvoid
- Xdiff_archive()
- X{
- X register char *data;
- X int fd, check, namelen, written;
- X int err, firsttime;
- X long size;
- X struct stat filestat;
- X char linkbuf[NAMSIZ+3];
- X
- X errno = EPIPE; /* FIXME, remove perrors */
- X
- X saverec(&head); /* Make sure it sticks around */
- X userec(head); /* And go past it in the archive */
- X decode_header(head, &hstat, &head_standard, 1); /* Snarf fields */
- X
- X /* Print the record from 'head' and 'hstat' */
- X if (f_verbose)
- X print_header(stdout);
- X
- X switch (head->header.linkflag) {
- X
- X default:
- X annofile(stderr, tar);
- X fprintf(stderr,
- X "Unknown file type '%c' for %s, diffed as normal file\n",
- X head->header.linkflag, head->header.name);
- X /* FALL THRU */
- X
- X case LF_OLDNORMAL:
- X case LF_NORMAL:
- X case LF_CONTIG:
- X /*
- X * Appears to be a file.
- X * See if it's really a directory.
- X */
- X namelen = strlen(head->header.name)-1;
- X if (head->header.name[namelen] == '/')
- X goto really_dir;
- X
- X fd = open(head->header.name, O_NDELAY|O_RDONLY);
- X
- X if (fd < 0) {
- X if (errno == ENOENT) {
- X /* Expected error -- to stdout */
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout, "%s: does not exist\n",
- X head->header.name);
- X } else {
- X annofile(stderr, (char *)NULL);
- X perror(head->header.name);
- X }
- X skip_file((long)hstat.st_size);
- X goto quit;
- X }
- X#ifdef AMIGA
- X err = stat(head->header.name, &filestat);
- X#else
- X err = fstat(fd, &filestat);
- X#endif
- X if (err < 0) {
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout, "Cannot fstat file ");
- X perror(head->header.name);
- X skip_file((long)hstat.st_size);
- X goto qclose;
- X }
- X
- X if ((filestat.st_mode & S_IFMT) != S_IFREG) {
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout, "%s: not a regular file\n",
- X head->header.name);
- X skip_file((long)hstat.st_size);
- X goto qclose;
- X }
- X
- X filestat.st_mode &= ~S_IFMT;
- X if (filestat.st_mode != hstat.st_mode)
- X sigh("mode");
- X if (filestat.st_uid != hstat.st_uid)
- X sigh("uid");
- X if (filestat.st_gid != hstat.st_gid)
- X sigh("gid");
- X if (filestat.st_size != hstat.st_size) {
- X sigh("size");
- X skip_file((long)hstat.st_size);
- X goto qclose;
- X }
- X if (filestat.st_mtime != hstat.st_mtime)
- X sigh("mod time");
- X
- X firsttime = 0;
- X
- X for (size = hstat.st_size;
- X size > 0;
- X size -= written) {
- X /*
- X * Locate data, determine max length
- X * writeable, write it, record that
- X * we have used the data, then check
- X * if the write worked.
- X */
- X data = findrec()->charptr;
- X if (data == NULL) { /* Check it... */
- X annorec(stderr, tar);
- X fprintf(stderr, "Unexpected EOF on archive file\n");
- X break;
- X }
- X written = endofrecs()->charptr - data;
- X if (written > size) written = size;
- X errno = 0;
- X check = read (fd, filedata, written);
- X /*
- X * The following is in violation of strict
- X * typing, since the arg to userec
- X * should be a struct rec *. FIXME.
- X */
- X userec(data + written - 1);
- X if (check == written) {
- X /* The read worked, now compare the data */
- X if (bcmp(data, filedata, check) == 0)
- X continue; /* It compares */
- X if (firsttime++) {
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout, "%s: data differs\n",
- X head->header.name);
- X }
- X }
- X
- X /*
- X * Error in reading from file.
- X * Print it, skip to next file in archive.
- X */
- X annofile(stderr, tar);
- X fprintf(stderr,
- X "Tried to read %d bytes from file, could only read %d:\n",
- X written, check);
- X perror(head->header.name);
- X skip_file((long)(size - written));
- X break; /* Still do the close, mod time, chmod, etc */
- X }
- X
- X qclose:
- X check = close(fd);
- X if (check < 0) {
- X annofile(stderr, tar);
- X fprintf(stderr, "Error while closing ");
- X perror(head->header.name);
- X }
- X
- X quit:
- X break;
- X
- X case LF_LINK:
- X check = 1; /* FIXME deal with this */
- X /* check = link (head->header.linkname,
- X head->header.name); */
- X /* FIXME, don't worry uid, gid, etc... */
- X if (check == 0)
- X break;
- X annofile(stderr, tar);
- X fprintf(stderr, "Could not link %s to ",
- X head->header.name);
- X perror(head->header.linkname);
- X break;
- X
- X#ifdef S_IFLNK
- X case LF_SYMLINK:
- X check = readlink(head->header.name, linkbuf,
- X (sizeof linkbuf)-1);
- X
- X if (check < 0) {
- X if (errno == ENOENT) {
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout,
- X "%s: no such file or directory\n",
- X head->header.name);
- X } else {
- X annofile(stderr, tar);
- X fprintf(stderr, "Could not read link");
- X perror(head->header.name);
- X }
- X break;
- X }
- X
- X linkbuf[check] = '\0'; /* Null-terminate it */
- X if (strncmp(head->header.linkname, linkbuf, check) != 0) {
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout, "%s: symlink differs\n",
- X head->header.linkname);
- X }
- X break;
- X#endif
- X
- X case LF_CHR:
- X hstat.st_mode |= S_IFCHR;
- X goto make_node;
- X
- X#ifdef S_IFBLK
- X /* If local system doesn't support block devices, use default case */
- X case LF_BLK:
- X hstat.st_mode |= S_IFBLK;
- X goto make_node;
- X#endif
- X
- X#ifdef S_IFIFO
- X /* If local system doesn't support FIFOs, use default case */
- X case LF_FIFO:
- X hstat.st_mode |= S_IFIFO;
- X hstat.st_rdev = 0; /* FIXME, do we need this? */
- X goto make_node;
- X#endif
- X
- X make_node:
- X /* FIXME, deal with umask */
- X
- X check = 1; /* FIXME, implement this */
- X /* check = mknod(head->header.name, (int) hstat.st_mode,
- X (int) hstat.st_rdev); */
- X if (check != 0) {
- X annofile(stderr, tar);
- X fprintf(stderr, "Could not make ");
- X perror(head->header.name);
- X break;
- X };
- X break;
- X
- X case LF_DIR:
- X /* Check for trailing / */
- X namelen = strlen(head->header.name)-1;
- X really_dir:
- X while (namelen && head->header.name[namelen] == '/')
- X head->header.name[namelen--] = '\0'; /* Zap / */
- X
- X check = 1; /* FIXME, implement this */
- X /* check = mkdir(head->header.name, 0300 | (int)hstat.st_mode); */
- X#ifndef AMIGA
- X if (check != 0) {
- X annofile(stderr, tar);
- X fprintf(stderr, "Could not make directory ");
- X perror(head->header.name);
- X break;
- X }
- X#endif
- X break;
- X
- X }
- X
- X /* We don't need to save it any longer. */
- X saverec((union record **) 0); /* Unsave it */
- X}
- X
- X/*
- X * Sigh about something that differs.
- X */
- Xsigh(what)
- X char *what;
- X{
- X
- X annofile(stdout, (char *)NULL);
- X fprintf(stdout, "%s: %s differs\n",
- X head->header.name, what);
- X}
- END_OF_FILE
- if test 7394 -ne `wc -c <'diffarch.c'`; then
- echo shar: \"'diffarch.c'\" unpacked with wrong size!
- fi
- # end of 'diffarch.c'
- fi
- if test -f 'dir.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dir.c'\"
- else
- echo shar: Extracting \"'dir.c'\" \(1611 characters\)
- sed "s/^X//" >'dir.c' <<'END_OF_FILE'
- X#include <dirent.h>
- X
- XDIR *
- Xopendir(char *dirname)
- X{
- X struct FileLock *alock;
- X struct FileInfoBlock *fib;
- X DIR *dp;
- X
- X if (alock = Lock(dirname, ACCESS_READ))
- X {
- X if ((fib = (struct FileInfoBlock *) malloc(sizeof(*fib))) == NULL)
- X {
- X UnLock(alock);
- X return(NULL); /* malloc failed */
- X }
- X if (Examine(alock, fib) && (fib->fib_DirEntryType > 0))
- X {
- X if (dp = (DIR *) malloc(sizeof(*dp)))
- X {
- X if ((dp->dd_dirent =
- X (struct dirent *) malloc(DIRENTSIZ(MAXNAMELEN))) == NULL)
- X {
- X UnLock(alock);
- X free(fib);
- X free(dp);
- X return(NULL); /* malloc failed */
- X }
- X dp->dd_lock = alock;
- X dp->dd_fib = fib;
- X dp->dd_loc = 0;
- X return(dp);
- X }
- X else
- X {
- X UnLock(alock);
- X free(fib);
- X return(NULL); /* malloc failed */
- X }
- X }
- X else
- X {
- X UnLock(alock);
- X free(fib);
- X return(NULL); /* not a directory */
- X }
- X }
- X else
- X return(NULL); /* couldn't access file */
- X}
- X
- X
- Xstruct dirent *
- Xreaddir(DIR *dirp)
- X{
- X struct dirent *dp;
- X
- X if ((dirp == NULL) || (dirp->dd_dirent == NULL))
- X return(NULL); /* malloc failed */
- X if (ExNext(dirp->dd_lock, dirp->dd_fib))
- X {
- X dirp->dd_loc++;
- X dp = dirp->dd_dirent;
- X dp->d_ino = 0;
- X dp->d_reclen = strlen(dirp->dd_fib->fib_FileName);
- X strcpy(dp->d_name, dirp->dd_fib->fib_FileName);
- X return(dirp->dd_dirent);
- X }
- X else
- X return(NULL); /* hit end */
- X}
- X
- Xint
- Xclosedir(DIR *dirp)
- X{
- X if ((dirp == NULL) || (dirp->dd_dirent == NULL))
- X return(1);
- X UnLock(dirp->dd_lock);
- X free(dirp->dd_dirent);
- X free(dirp->dd_fib);
- X free(dirp);
- X return(0);
- X}
- END_OF_FILE
- if test 1611 -ne `wc -c <'dir.c'`; then
- echo shar: \"'dir.c'\" unpacked with wrong size!
- fi
- # end of 'dir.c'
- fi
- if test -f 'dirent.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dirent.h'\"
- else
- echo shar: Extracting \"'dirent.h'\" \(899 characters\)
- sed "s/^X//" >'dirent.h' <<'END_OF_FILE'
- X/*
- X * dirent.h for AmigaDOS - derived from an old document written by Doug Gwyn
- X *
- X * $Header$
- X */
- X#include <sys/types.h>
- X#include <libraries/dosextens.h>
- X#include <proto/dos.h>
- X
- X#define MAXNAMELEN 108 /* space in FIB for name */
- X
- X#ifndef NAME_MAX
- X#define NAME_MAX (MAXNAMELEN - 1)
- X#endif
- X
- Xstruct dirent {
- X long d_ino;
- X off_t d_off;
- X unsigned short d_reclen;
- X char d_name[1];
- X};
- X
- Xtypedef struct {
- X struct dirent *dd_dirent; /* ok to reuse this over and over */
- X struct FileLock *dd_lock;
- X struct FileInfoBlock *dd_fib;
- X int dd_loc;
- X} DIR;
- X
- X#define DIRENTBASESIZ (&((struct dirent *) 0)->d_name \
- X - (char *) &((struct dirent *) 0)->d_ino)
- X#define DIRENTSIZ(namelen) ((DIRENTBASESIZ + sizeof(long) + (namelen)) \
- X / sizeof(long) * 4)
- X
- XDIR *opendir(char *dirname);
- Xstruct dirent *readdir(DIR *dirp);
- Xoff_t telldir(DIR *dirp);
- Xvoid seekdir(DIR *dirp, off_t loc);
- Xvoid rewinddir(DIR *dirp);
- END_OF_FILE
- if test 899 -ne `wc -c <'dirent.h'`; then
- echo shar: \"'dirent.h'\" unpacked with wrong size!
- fi
- # end of 'dirent.h'
- fi
- if test -f 'getoldopt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'getoldopt.c'\"
- else
- echo shar: Extracting \"'getoldopt.c'\" \(1374 characters\)
- sed "s/^X//" >'getoldopt.c' <<'END_OF_FILE'
- X/*
- X * Plug-compatible replacement for getopt() for parsing tar-like
- X * arguments. If the first argument begins with "-", it uses getopt;
- X * otherwise, it uses the old rules used by tar, dump, and ps.
- X *
- X * Written 25 August 1985 by John Gilmore (ihnp4!hoptoad!gnu) and placed
- X * in the Pubic Domain for your edification and enjoyment.
- X *
- X * @(#)getoldopt.c 1.4 2/4/86 Public Domain - gnu
- X */
- X
- X#include <stdio.h>
- X
- X
- Xint
- Xgetoldopt(argc, argv, optstring)
- X int argc;
- X char **argv;
- X char *optstring;
- X{
- X extern char *optarg; /* Points to next arg */
- X extern int optind; /* Global argv index */
- X static char *key; /* Points to next keyletter */
- X static char use_getopt; /* !=0 if argv[1][0] was '-' */
- X extern char *index();
- X char c;
- X char *place;
- X
- X optarg = NULL;
- X
- X if (key == NULL) { /* First time */
- X if (argc < 2) return EOF;
- X key = argv[1];
- X if (*key == '-')
- X use_getopt++;
- X else
- X optind = 2;
- X }
- X
- X if (use_getopt)
- X return getopt(argc, argv, optstring);
- X
- X c = *key++;
- X if (c == '\0') {
- X key--;
- X return EOF;
- X }
- X place = index(optstring, c);
- X
- X if (place == NULL || c == ':') {
- X fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
- X return('?');
- X }
- X
- X place++;
- X if (*place == ':') {
- X if (optind < argc) {
- X optarg = argv[optind];
- X optind++;
- X } else {
- X fprintf(stderr, "%s: %c argument missing\n",
- X argv[0], c);
- X return('?');
- X }
- X }
- X
- X return(c);
- X}
- END_OF_FILE
- if test 1374 -ne `wc -c <'getoldopt.c'`; then
- echo shar: \"'getoldopt.c'\" unpacked with wrong size!
- fi
- # end of 'getoldopt.c'
- fi
- if test -f 'getopt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'getopt.c'\"
- else
- echo shar: Extracting \"'getopt.c'\" \(1489 characters\)
- sed "s/^X//" >'getopt.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X
- X/*
- X * get option letter from argument vector
- X */
- Xint opterr = 1; /* useless, never set or used */
- Xint optind = 1; /* index into parent argv vector */
- Xint optopt; /* character checked for validity */
- Xchar *optarg; /* argument associated with option */
- X
- X#define BADCH (int)'?'
- X#define EMSG ""
- X#define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \
- X fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
- X
- Xgetopt(nargc,nargv,ostr)
- Xint nargc;
- Xchar **nargv,
- X *ostr;
- X{
- X static char *place = EMSG; /* option letter processing */
- X register char *oli; /* option letter list index */
- X char *index();
- X
- X/* fprintf(stderr, "getopt(): optind=%d optarg=0x%x\n", optind, optarg); */
- X if(!*place) { /* update scanning pointer */
- X if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
- X if (*place == '-') { /* found "--" */
- X ++optind;
- X return(EOF);
- X }
- X } /* option letter okay? */
- X if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
- X if(!*place) ++optind;
- X tell(": illegal option -- ");
- X }
- X if (*++oli != ':') { /* don't need argument */
- X optarg = NULL;
- X if (!*place) ++optind;
- X }
- X else { /* need an argument */
- X if (*place) optarg = place; /* no white space */
- X else if (nargc <= ++optind) { /* no arg */
- X place = EMSG;
- X tell(": option requires an argument -- ");
- X }
- X else optarg = nargv[optind]; /* white space */
- X place = EMSG;
- X ++optind;
- X }
- X return(optopt); /* dump back option letter */
- X}
- X
- END_OF_FILE
- if test 1489 -ne `wc -c <'getopt.c'`; then
- echo shar: \"'getopt.c'\" unpacked with wrong size!
- fi
- # end of 'getopt.c'
- fi
- if test -f 'open3.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'open3.h'\"
- else
- echo shar: Extracting \"'open3.h'\" \(1906 characters\)
- sed "s/^X//" >'open3.h' <<'END_OF_FILE'
- X/*
- X * @(#)open3.h 1.4 87/11/11 Public Domain.
- X *
- X * open3.h -- #defines for the various flags for the Sys V style 3-argument
- X * open() call. On BSD or System 5, the system already has this in an
- X * include file. This file is needed for V7 and MINIX systems for the
- X * benefit of open3() in port.c, a routine that emulates the 3-argument
- X * call using system calls available on V7/MINIX.
- X *
- X * This file is needed by PD tar even if we aren't using the
- X * emulator, since the #defines for O_WRONLY, etc. are used in
- X * a couple of places besides the open() calls, (e.g. in the assignment
- X * to openflag in extract.c). We just #include this rather than
- X * #ifdef them out.
- X *
- X * Written 6/10/87 by rmtodd@uokmax (Richard Todd).
- X *
- X * The names have been changed by John Gilmore, 31 July 1987, since
- X * Richard called it "bsdopen", and really this change was introduced in
- X * AT&T Unix systems before BSD picked it up.
- X */
- X
- X/* Only one of the next three should be specified */
- X#define O_RDONLY 0 /* only allow read */
- X#define O_WRONLY 1 /* only allow write */
- X#define O_RDWR 2 /* both are allowed */
- X
- X/* The rest of these can be OR-ed in to the above. */
- X/*
- X * O_NDELAY isn't implemented by the emulator. It's only useful (to tar) on
- X * systems that have named pipes anyway; it prevents tar's hanging by
- X * opening a named pipe. We #ifndef it because some systems already have
- X * it defined.
- X */
- X#ifndef O_NDELAY
- X#define O_NDELAY 4 /* don't block on opening devices that would
- X * block on open -- ignored by emulator. */
- X#endif
- X#define O_CREAT 8 /* create file if needed */
- X#define O_EXCL 16 /* file cannot already exist */
- X#define O_TRUNC 32 /* truncate file on open */
- X#define O_APPEND 64 /* always write at end of file -- ignored by emul */
- X
- X#ifdef EMUL_OPEN3
- X/*
- X * make emulation transparent to rest of file -- redirect all open() calls
- X * to our routine
- X */
- X#define open open3
- X#endif
- END_OF_FILE
- if test 1906 -ne `wc -c <'open3.h'`; then
- echo shar: \"'open3.h'\" unpacked with wrong size!
- fi
- # end of 'open3.h'
- fi
- if test -f 'port.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'port.h'\"
- else
- echo shar: Extracting \"'port.h'\" \(929 characters\)
- sed "s/^X//" >'port.h' <<'END_OF_FILE'
- X/*
- X * Portability declarations for public domain tar.
- X *
- X * @(#)port.h 1.3 87/11/11 Public Domain by John Gilmore, 1986
- X */
- X
- X/*
- X * Everybody does wait() differently. There seem to be no definitions
- X * for this in V7 (e.g. you are supposed to shift and mask things out
- X * using constant shifts and masks.) So fuck 'em all -- my own non
- X * standard but portable macros. Don't change to a "union wait"
- X * based approach -- the ordering of the elements of the struct
- X * depends on the byte-sex of the machine. Foo!
- X */
- X#define TERM_SIGNAL(status) ((status) & 0x7F)
- X#define TERM_COREDUMP(status) (((status) & 0x80) != 0)
- X#define TERM_VALUE(status) ((status) >> 8)
- X
- X#if defined(MSDOS) || defined(AMIGA)
- X/* missing things from sys/stat.h */
- X#define S_ISUID 0
- X#define S_ISGID 0
- X#define S_ISVTX 0
- X
- X/* device stuff */
- X#define makedev(ma, mi) ((ma << 8) | mi)
- X#define major(dev) (dev)
- X#define minor(dev) (dev)
- X#endif /* MSDOS */
- END_OF_FILE
- if test 929 -ne `wc -c <'port.h'`; then
- echo shar: \"'port.h'\" unpacked with wrong size!
- fi
- # end of 'port.h'
- fi
- if test -f 'stat.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stat.h'\"
- else
- echo shar: Extracting \"'stat.h'\" \(426 characters\)
- sed "s/^X//" >'stat.h' <<'END_OF_FILE'
- X#include <libraries/dos.h>
- X
- Xstruct stat {
- X int st_mode;
- X int st_dev;
- X int st_ino;
- X int st_size;
- X int st_rdev;
- X int st_gid;
- X int st_uid;
- X int st_mtime;
- X int st_nlink;
- X/*
- X * These last fields are specific to the Amiga
- X */
- X struct DateStamp st_date;
- X u_long st_prot;
- X char st_comment[80]; /* header files says last 36 bytes unused */
- X};
- X
- X#define S_IFREG 01000
- X#define S_IFDIR 02000
- X#define S_IFCHR 04000
- X#define S_IFMT 07000
- END_OF_FILE
- if test 426 -ne `wc -c <'stat.h'`; then
- echo shar: \"'stat.h'\" unpacked with wrong size!
- fi
- # end of 'stat.h'
- fi
- if test -f 'tar.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tar.h'\"
- else
- echo shar: Extracting \"'tar.h'\" \(5813 characters\)
- sed "s/^X//" >'tar.h' <<'END_OF_FILE'
- X/*
- X * Header file for public domain tar (tape archive) program.
- X *
- X * @(#)tar.h 1.24 87/11/06 Public Domain.
- X *
- X * Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
- X */
- X
- X/*
- X * Kludge for handling systems that can't cope with multiple
- X * external definitions of a variable. In ONE routine (tar.c),
- X * we #define TAR_EXTERN to null; here, we set it to "extern" if
- X * it is not already set.
- X */
- X#ifndef TAR_EXTERN
- X#define TAR_EXTERN extern
- X#endif
- X
- X/*
- X * Header block on tape.
- X *
- X * I'm going to use traditional DP naming conventions here.
- X * A "block" is a big chunk of stuff that we do I/O on.
- X * A "record" is a piece of info that we care about.
- X * Typically many "record"s fit into a "block".
- X */
- X#define RECORDSIZE 512
- X#define NAMSIZ 100
- X#define TUNMLEN 32
- X#define TGNMLEN 32
- X
- Xunion record {
- X char charptr[RECORDSIZE];
- X struct header {
- X char name[NAMSIZ];
- X char mode[8];
- X char uid[8];
- X char gid[8];
- X char size[12];
- X char mtime[12];
- X char chksum[8];
- X char linkflag;
- X char linkname[NAMSIZ];
- X char magic[8];
- X char uname[TUNMLEN];
- X char gname[TGNMLEN];
- X char devmajor[8];
- X char devminor[8];
- X#ifdef AMIGA
- X char magic_cookie[9]; /* "AmigaTar" */
- X char amiga_modes[9]; /* Protection, hex ascii */
- X char comment[80]; /* Comment */
- X char ds_Days[9]; /* Date Stamp, hex ascii */
- X char ds_Minute[9]; /* Date Stamp, hex ascii */
- X char ds_Tick[9]; /* Date Stamp, hex ascii */
- X#endif
- X } header;
- X};
- X
- X/* The checksum field is filled with this while the checksum is computed. */
- X#define CHKBLANKS " " /* 8 blanks, no null */
- X
- X/* The magic field is filled with this if uname and gname are valid. */
- X#define TMAGIC "ustar " /* 7 chars and a null */
- X
- X/* The linkflag defines the type of file */
- X#define LF_OLDNORMAL '\0' /* Normal disk file, Unix compat */
- X#define LF_NORMAL '0' /* Normal disk file */
- X#define LF_LINK '1' /* Link to previously dumped file */
- X#define LF_SYMLINK '2' /* Symbolic link */
- X#define LF_CHR '3' /* Character special file */
- X#define LF_BLK '4' /* Block special file */
- X#define LF_DIR '5' /* Directory */
- X#define LF_FIFO '6' /* FIFO special file */
- X#define LF_CONTIG '7' /* Contiguous file */
- X/* Further link types may be defined later. */
- X
- X/*
- X * Exit codes from the "tar" program
- X */
- X#define EX_SUCCESS 0 /* success! */
- X#define EX_ARGSBAD 1 /* invalid args */
- X#define EX_BADFILE 2 /* invalid filename */
- X#define EX_BADARCH 3 /* bad archive */
- X#define EX_SYSTEM 4 /* system gave unexpected error */
- X
- X
- X/*
- X * Global variables
- X */
- XTAR_EXTERN union record *ar_block; /* Start of block of archive */
- XTAR_EXTERN union record *ar_record; /* Current record of archive */
- XTAR_EXTERN union record *ar_last; /* Last+1 record of archive block */
- XTAR_EXTERN char ar_reading; /* 0 writing, !0 reading archive */
- XTAR_EXTERN int blocking; /* Size of each block, in records */
- XTAR_EXTERN int blocksize; /* Size of each block, in bytes */
- XTAR_EXTERN char *ar_file; /* File containing archive */
- XTAR_EXTERN char *name_file; /* File containing names to work on */
- XTAR_EXTERN char *tar; /* Name of this program */
- X
- X/*
- X * Flags from the command line
- X */
- X#ifdef AMIGA
- XTAR_EXTERN char f_archive_set; /* -a */
- XTAR_EXTERN char f_archive_check; /* -A */
- X#endif
- XTAR_EXTERN char f_reblock; /* -B */
- XTAR_EXTERN char f_create; /* -c */
- XTAR_EXTERN char f_diff; /* -d */
- XTAR_EXTERN char f_dironly; /* -D */
- XTAR_EXTERN char f_follow_links; /* -h */
- XTAR_EXTERN char f_ignorez; /* -i */
- XTAR_EXTERN char f_keep; /* -k */
- XTAR_EXTERN char f_local_filesys; /* -l */
- XTAR_EXTERN char f_modified; /* -m */
- XTAR_EXTERN char f_oldarch; /* -o */
- XTAR_EXTERN char f_use_protection; /* -p */
- XTAR_EXTERN char f_sayblock; /* -R */
- XTAR_EXTERN char f_sorted_names; /* -s */
- XTAR_EXTERN char f_list; /* -t */
- XTAR_EXTERN char f_namefile; /* -T */
- XTAR_EXTERN char f_verbose; /* -v */
- XTAR_EXTERN char f_extract; /* -x */
- XTAR_EXTERN char f_compress; /* -z */
- X
- X/*
- X * We now default to Unix Standard format rather than 4.2BSD tar format.
- X * The code can actually produce all three:
- X * f_standard ANSI standard
- X * f_oldarch V7
- X * neither 4.2BSD
- X * but we don't bother, since 4.2BSD can read ANSI standard format anyway.
- X * The only advantage to the "neither" option is that we can cmp(1) our
- X * output to the output of 4.2BSD tar, for debugging.
- X */
- X#define f_standard (!f_oldarch)
- X
- X/*
- X * Structure for keeping track of filenames and lists thereof.
- X */
- Xstruct name {
- X struct name *next;
- X short length; /* cached strlen(name) */
- X char found; /* A matching file has been found */
- X char firstch; /* First char is literally matched */
- X char regexp; /* This name is a regexp, not literal */
- X char name[NAMSIZ+1];
- X};
- X
- XTAR_EXTERN struct name *namelist; /* Points to first name in list */
- XTAR_EXTERN struct name *namelast; /* Points to last name in list */
- X
- XTAR_EXTERN int archive; /* File descriptor for archive file */
- XTAR_EXTERN int errors; /* # of files in error */
- X
- X/*
- X *
- X * Due to the next struct declaration, each routine that includes
- X * "tar.h" must also include <sys/types.h>. I tried to make it automatic,
- X * but System V has no defines in <sys/types.h>, so there is no way of
- X * knowing when it has been included. In addition, it cannot be included
- X * twice, but must be included exactly once. Argghh!
- X *
- X * Thanks, typedef. Thanks, USG.
- X */
- Xstruct link {
- X struct link *next;
- X dev_t dev;
- X ino_t ino;
- X short linkcount;
- X char name[NAMSIZ+1];
- X};
- X
- XTAR_EXTERN struct link *linklist; /* Points to first link in list */
- X
- X
- X/*
- X * Error recovery stuff
- X */
- XTAR_EXTERN char read_error_flag;
- X
- X
- X/*
- X * Declarations of functions available to the world.
- X */
- Xunion record *findrec();
- Xvoid userec();
- Xunion record *endofrecs();
- Xvoid anno();
- X#define annorec(stream, msg) anno(stream, msg, 0) /* Cur rec */
- X#define annofile(stream, msg) anno(stream, msg, 1) /* Saved rec */
- END_OF_FILE
- if test 5813 -ne `wc -c <'tar.h'`; then
- echo shar: \"'tar.h'\" unpacked with wrong size!
- fi
- # end of 'tar.h'
- fi
- if test -f 'tar.lnk' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tar.lnk'\"
- else
- echo shar: Extracting \"'tar.lnk'\" \(198 characters\)
- sed "s/^X//" >'tar.lnk' <<'END_OF_FILE'
- XFROM LIB:c.o+"tar.o"+"buffer.o"+"create.o"+"diffarch.o"+"extract.o"+"getoldopt.o"+"getopt.o"+"list.o"+"port.o"+"wildmat.o"+
- X"utime.o"+"/dirlib/dir.o"+"amiga.o"
- XTO "tar"
- XLIB LIB:lc.lib LIB:amiga.lib
- END_OF_FILE
- if test 198 -ne `wc -c <'tar.lnk'`; then
- echo shar: \"'tar.lnk'\" unpacked with wrong size!
- fi
- # end of 'tar.lnk'
- fi
- if test -f 'types.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'types.h'\"
- else
- echo shar: Extracting \"'types.h'\" \(210 characters\)
- sed "s/^X//" >'types.h' <<'END_OF_FILE'
- Xtypedef unsigned long u_long;
- Xtypedef unsigned int u_int;
- Xtypedef unsigned short u_short;
- Xtypedef unsigned char u_char;
- Xtypedef int dev_t;
- Xtypedef int ino_t;
- Xtypedef unsigned short off_t;
- Xtypedef int time_t;
- END_OF_FILE
- if test 210 -ne `wc -c <'types.h'`; then
- echo shar: \"'types.h'\" unpacked with wrong size!
- fi
- # end of 'types.h'
- fi
- if test -f 'utime.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'utime.c'\"
- else
- echo shar: Extracting \"'utime.c'\" \(4532 characters\)
- sed "s/^X//" >'utime.c' <<'END_OF_FILE'
- X/*
- X * TITLE: touch.c This is a simple command to set the date of a file to
- X * now. It was compiled using Greenhills C. You might have to change it a
- X * little for use with Lattice or Manx. The program compiles with just
- X * amigalib. (that's why those string functions are tacked on the end of
- X * the file)
- X */
- X
- X/*
- X * Changed to be utime function by Jonathan Hue
- X */
- X
- X/* touch.c by Phil Lindsay and Andy Finkel */
- X/* (c) 1986 Commodore-Amiga, Inc. */
- X/* Permission to use in any way granted, as long as */
- X/* the copyright notice stays intact */
- X
- X#include "exec/types.h"
- X#include "exec/ports.h"
- X#include "exec/io.h"
- X#include "exec/memory.h"
- X#include "libraries/dos.h"
- X#include "libraries/dosextens.h"
- X#include <sys/types.h>
- X#include <errno.h>
- X
- Xextern LONG sendpkt();
- X
- X#define ACTION_SET_DATE 34
- X
- Xstatic struct DateStamp *seconds2AmiTime();
- X
- Xint
- Xutime(char *filename, time_t unixtime[2])
- X{
- X struct DateStamp dateStamp;
- X
- X return(utime_from_stamp(filename, seconds2AmiTime(unixtime[1]),
- X &dateStamp));
- X}
- X
- Xint
- Xutime_from_stamp(char *filename, struct DateStamp *ds)
- X{
- X struct MsgPort *task;
- X struct FileInfoBlock *fib;
- X LONG arg[4];
- X LONG rc;
- X ULONG lock;
- X ULONG plock;
- X UBYTE *pointer;
- X
- X pointer = NULL;
- X if (!(pointer = (UBYTE *) AllocMem(64, MEMF_PUBLIC)))
- X {
- X errno = ENOMEM;
- X return(-1);
- X }
- X if (!(task = (struct MsgPort *) DeviceProc(filename)))
- X {
- X FreeMem(pointer, 64);
- X errno = ENOENT;
- X return(-1);
- X }
- X if (!(lock = (ULONG) Lock(filename, SHARED_LOCK)))
- X {
- X FreeMem(pointer, 64);
- X errno = ENOENT;
- X return(-1);
- X }
- X plock = (ULONG) ParentDir(lock);
- X if (!plock) /* filename is root dir, can't set time */
- X {
- X FreeMem(pointer, 64); /* sometimes you almost want to use a goto */
- X errno = EACCES;
- X UnLock(lock);
- X return(-1);
- X }
- X if (!(fib = malloc(sizeof(*fib))))
- X {
- X FreeMem(pointer, 64);
- X errno = ENOMEM;
- X UnLock(lock);
- X return(-1);
- X }
- X Examine(lock, fib);
- X UnLock(lock);
- X strcpy((pointer + 1), fib->fib_FileName);
- X *pointer = strlen(fib->fib_FileName);
- X free(fib);
- X arg[0] = NULL;
- X arg[1] = plock;
- X arg[2] = (ULONG) & pointer[0] >> 2; /* BSTR of filename */
- X arg[3] = (ULONG) ds; /* DateStamp */
- X rc = sendpkt(task, ACTION_SET_DATE, arg, 4);
- X
- X UnLock(plock);
- X FreeMem(pointer, 64);
- X return (0);
- X}
- X
- X
- XLONG
- Xsendpkt(id, type, args, nargs)
- Xstruct MsgPort *id;/* process indentifier ... (handlers message port ) */
- XLONG type; /* packet type ... (what you want handler to do ) */
- XLONG args[]; /* a pointer to a argument list */
- XLONG nargs; /* number of arguments in list */
- X{
- X
- X struct MsgPort *replyport;
- X struct StandardPacket *packet = NULL;
- X LONG count;
- X LONG *pargs;
- X LONG res1 = NULL;
- X
- X
- X if (!(replyport = (struct MsgPort *) CreatePort(NULL, NULL)))
- X return (NULL);
- X
- X packet = (struct StandardPacket *)
- X AllocMem((LONG) sizeof(*packet), MEMF_PUBLIC | MEMF_CLEAR);
- X
- X if (packet)
- X {
- X packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt); /* link packet */
- X packet->sp_Pkt.dp_Link = &(packet->sp_Msg); /* to message */
- X packet->sp_Pkt.dp_Port = replyport; /* set-up reply port */
- X packet->sp_Pkt.dp_Type = type; /* what to do... */
- X
- X /* move all the arguments to the packet */
- X pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first
- X * argument */
- X for (count = 0; (count < nargs) && (count < 7); count++)
- X pargs[count] = args[count];
- X
- X PutMsg(id, packet); /* send packet */
- X WaitPort(replyport); /* wait for packet to come back */
- X GetMsg(replyport); /* pull message */
- X
- X res1 = packet->sp_Pkt.dp_Res1; /* get result */
- X FreeMem(packet, (LONG) sizeof(*packet));
- X
- X }
- X DeletePort(replyport);
- X return (res1);
- X}
- X
- X/*
- X * Convert seconds into Amiga style time (days since 1/1/78, minutes since
- X * 12AM, ticks this hour)
- X */
- Xstatic struct DateStamp *
- Xseconds2AmiTime(long secs, struct DateStamp *ds)
- X{
- X extern long timezone;
- X
- X /* seconds is in GMT, so compensate */
- X secs -= timezone;
- X
- X /* Subtract 8 years worth of seconds, including 2 leap years */
- X secs -= ((6 * 365) + (2 * 366)) * (60 * 60 * 24);
- X
- X /* Now have seconds since 1/1/78, get days */
- X ds->ds_Days = secs / (60 * 60 * 24);
- X secs -= ds->ds_Days * (60 * 60 * 24);
- X
- X /* Now have seconds since midnight, get minutes */
- X ds->ds_Minute = secs / 60;
- X secs -= ds->ds_Minute * 60;
- X
- X /* Now have seconds this minute, convert to ticks */
- X ds->ds_Tick = secs * 50;
- X return(ds);
- X}
- END_OF_FILE
- if test 4532 -ne `wc -c <'utime.c'`; then
- echo shar: \"'utime.c'\" unpacked with wrong size!
- fi
- # end of 'utime.c'
- fi
- if test -f 'wildmat.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'wildmat.c'\"
- else
- echo shar: Extracting \"'wildmat.c'\" \(3462 characters\)
- sed "s/^X//" >'wildmat.c' <<'END_OF_FILE'
- X/*
- X * @(#)wildmat.c 1.3 87/11/06 Public Domain.
- X *
- XFrom: rs@mirror.TMC.COM (Rich Salz)
- XNewsgroups: net.sources
- XSubject: Small shell-style pattern matcher
- XMessage-ID: <596@mirror.TMC.COM>
- XDate: 27 Nov 86 00:06:40 GMT
- X
- XThere have been several regular-expression subroutines and one or two
- Xfilename-globbing routines in mod.sources. They handle lots of
- Xcomplicated patterns. This small piece of code handles the *?[]\
- Xwildcard characters the way the standard Unix(tm) shells do, with the
- Xaddition that "[^.....]" is an inverse character class -- it matches
- Xany character not in the range ".....". Read the comments for more
- Xinfo.
- X
- XFor my application, I had first ripped off a copy of the "glob" routine
- Xfrom within the find(1) source, but that code is bad news: it recurses
- Xon every character in the pattern. I'm putting this replacement in the
- Xpublic domain. It's small, tight, and iterative. Compile with -DTEST
- Xto get a test driver. After you're convinced it works, install in
- Xwhatever way is appropriate for you.
- X
- XI would like to hear of bugs, but am not interested in additions; if I
- Xwere, I'd use the code I mentioned above.
- X*/
- X/*
- X** Do shell-style pattern matching for ?, \, [], and * characters.
- X** Might not be robust in face of malformed patterns; e.g., "foo[a-"
- X** could cause a segmentation violation.
- X**
- X** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
- X*/
- X
- X/*
- X * Modified 6Nov87 by John Gilmore (hoptoad!gnu) to return a "match"
- X * if the pattern is immediately followed by a "/", as well as \0.
- X * This matches what "tar" does for matching whole subdirectories.
- X *
- X * The "*" code could be sped up by only recursing one level instead
- X * of two for each trial pattern, perhaps, and not recursing at all
- X * if a literal match of the next 2 chars would fail.
- X */
- X#define TRUE 1
- X#define FALSE 0
- X
- X
- Xstatic int
- XStar(s, p)
- X register char *s;
- X register char *p;
- X{
- X while (wildmat(s, p) == FALSE)
- X if (*++s == '\0')
- X return(FALSE);
- X return(TRUE);
- X}
- X
- X
- Xint
- Xwildmat(s, p)
- X register char *s;
- X register char *p;
- X{
- X register int last;
- X register int matched;
- X register int reverse;
- X
- X for ( ; *p; s++, p++)
- X switch (*p) {
- X case '\\':
- X /* Literal match with following character; fall through. */
- X p++;
- X default:
- X if (*s != *p)
- X return(FALSE);
- X continue;
- X case '?':
- X /* Match anything. */
- X if (*s == '\0')
- X return(FALSE);
- X continue;
- X case '*':
- X /* Trailing star matches everything. */
- X return(*++p ? Star(s, p) : TRUE);
- X case '[':
- X /* [^....] means inverse character class. */
- X if (reverse = p[1] == '^')
- X p++;
- X for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
- X /* This next line requires a good C compiler. */
- X if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
- X matched = TRUE;
- X if (matched == reverse)
- X return(FALSE);
- X continue;
- X }
- X
- X /* For "tar" use, matches that end at a slash also work. --hoptoad!gnu */
- X return(*s == '\0' || *s == '/');
- X}
- X
- X
- X#ifdef TEST
- X#include <stdio.h>
- X
- Xextern char *gets();
- X
- X
- Xmain()
- X{
- X char pattern[80];
- X char text[80];
- X
- X while (TRUE) {
- X printf("Enter pattern: ");
- X if (gets(pattern) == NULL)
- X break;
- X while (TRUE) {
- X printf("Enter text: ");
- X if (gets(text) == NULL)
- X exit(0);
- X if (text[0] == '\0')
- X /* Blank line; go back and get a new pattern. */
- X break;
- X printf(" %d\n", wildmat(text, pattern));
- X }
- X }
- X exit(0);
- X}
- X#endif /* TEST */
- END_OF_FILE
- if test 3462 -ne `wc -c <'wildmat.c'`; then
- echo shar: \"'wildmat.c'\" unpacked with wrong size!
- fi
- # end of 'wildmat.c'
- fi
- echo shar: End of archive 1 \(of 5\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 5 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
- Mail comments to the moderator at <amiga-request@cs.odu.edu>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-